package model;

public class NodeConnection {
	private Tracker tracker;
	private Node upNode;
	private Node downNode;
	private FilePiece filePiece;
	private double dataTransferred = 0;
	private double bandwidth;
	public NodeConnection(Tracker tracker, Node upNode, Node downNode, FilePiece filePiece, double bandwidth){
		this.tracker = tracker;
		this.upNode = upNode;
		this.downNode = downNode;
		this.filePiece = filePiece;
		this.bandwidth = bandwidth;
		notifyConnectionInitiated();
	}
	
	
	public boolean isTransferComplete(){
		return dataTransferred>=getFilePiece().getDataSize();
	}
	
	private void notifyConnectionInitiated(){
		getUpNode().notifyConnectionInitiated(this);
		getDownNode().notifyConnectionInitiated(this);
	}
	
	private void notifyConnectionCompleted(){
		getUpNode().notifyConnectionCompleted(this);
		getDownNode().notifyConnectionCompleted(this);
		tracker.notifyConnectionCompleted(this);
	}
	
	public void notifyNodeDisconnected(Node node){
		if(node==upNode){
			downNode.dropConnection(this);
		} else if(node==downNode){
			upNode.dropConnection(this);
		}
	}


	public Node getUpNode() {
		return upNode;
	}


	public Node getDownNode() {
		return downNode;
	}


	public FilePiece getFilePiece() {
		return filePiece;
	}

	public double getBandwidth() {
		return bandwidth;
	}
	
	public int update(){
		testConnectionUpgrade();
		if(dataTransferred<filePiece.getDataSize()){
			dataTransferred += bandwidth;
			upNode.notifyDataSent(bandwidth);
			downNode.notifyDataRecived(bandwidth);
			if(dataTransferred>=filePiece.getDataSize()){
				upNode.notifyDataSent(dataTransferred-filePiece.getDataSize());
				downNode.notifyDataRecived(dataTransferred-filePiece.getDataSize());
				dataTransferred = filePiece.getDataSize();
				notifyConnectionCompleted();
				return 1;
			}
		}	
		return 0;
	}
	
	public double getDataTransferred(){
		return dataTransferred;
	}
	
	@Override
	public String toString(){
		double percentComplete = dataTransferred/filePiece.getDataSize() * 100;
		String stringPercent = Double.toString(percentComplete);
		stringPercent = stringPercent.substring(0, (stringPercent.indexOf('.')+3 > stringPercent.length()) ? stringPercent.length() : stringPercent.indexOf('.')+3);
		
		String bandString = Double.toString(bandwidth);
		bandString = bandString.substring(0, (bandString.indexOf('.')+3 > bandString.length()) ? bandString.length() : bandString.indexOf('.')+3);
		
		return filePiece.getNumber() + "\t" + upNode.getNumber() + "\t\t" + downNode.getNumber() + "\t\t" + bandString + "\t\t" + stringPercent;
	}
	
	private void testConnectionUpgrade(){
		if(upNode.upBandwidthRemaining() > bandwidth && downNode.downBandwidthRemaining() > bandwidth){
			bandwidth = (upNode.upBandwidthRemaining() < downNode.downBandwidthRemaining()) ? upNode.upBandwidthRemaining() : downNode.downBandwidthRemaining();
		}
	}
}
